iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
0
Software Development

從Java進入AWS部署RESTful API的心路歷程系列 第 16

Day16-概觀(六)操作DynamoDB

  • 分享至 

  • xImage
  •  

有多種介面或方式可以進行DynamoDB的操作,包含

  • GUI - AWS雲端上的控制台、DynamoDB-Local的web shell
  • low-level web api
  • CLI - 使用AWS DynamoDB CLI
  • 使用支援的語言撰寫程式,透過SDK操作
  • CloudFormation

為了方便一開始的開發測試,我們先來看看web shell跟CLI

API Reference

API 參考

首先稍微看一下API提供的Action,我想最應該先了解的自然是

  • CreateTable
  • GetItem
  • PutItem
  • UpdateItem
  • DeleteItem

稍微點幾個來看,都會看到以JSON format定義的Request Syntax,因為了解這個就能很簡單地透過參數在web shell或AWS CLI執行指令,所以我們先來看一下。

建立資料表

首先來試試透過web shell建立最基本的資料表

var params = {
    "TableName": "table1",
    "AttributeDefinitions": [
        {
            "AttributeName": "pk_id",
            "AttributeType": "S"
        }
    ],
    "KeySchema": [
        {
            "AttributeName": "pk_id",
            "KeyType": "HASH"
        }
    ],
    "ProvisionedThroughput": { 
      "ReadCapacityUnits": 1,
      "WriteCapacityUnits": 1
   }
 };
 dynamodb.createTable(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

ProvisionedThroughput屬性定義讀取/寫入容量模式,這跟實際上線使用情況有關,我們先不看它。

從之前DynamoDB核心元件的了解來看,我沒最少會需要定義Partition key,也就是KeyType為HASH的屬性。但是在這之前,我們所有定義會用到的屬性,都要在AttributeDefinitions當中明確定義其名字與類型。當然我們還需要定義資料表名稱。

在web shell執行這段javascript後,即會看到定義好的資料表資料。

{"TableDescription":{"AttributeDefinitions":[{"AttributeName":"pk_id","AttributeType":"S"}],"TableName":"table1","KeySchema":[{"AttributeName":"pk_id","KeyType":"HASH"}],"TableStatus":"ACTIVE","CreationDateTime":"2019-09-27T15:19:11.046Z","ProvisionedThroughput":{"LastIncreaseDateTime":"1970-01-01T00:00:00.000Z","LastDecreaseDateTime":"1970-01-01T00:00:00.000Z","NumberOfDecreasesToday":0,"ReadCapacityUnits":1,"WriteCapacityUnits":1},"TableSizeBytes":0,"ItemCount":0,"TableArn":"arn:aws:dynamodb:ddblocal:000000000000:table/table1"}}

回頭試試上次用過的listTable指令

{
    "TableNames": [
        "table1"
    ]
}

寫入資料

我們看到有PutItem與UpdateItem兩種指令

來試試PutItem吧

var params = {
    "TableName": "table1",
    "Item": {
        "pk_id": {
            "S": "201909270001"
        },
        "Tags": {
            "SS": ["Update","Multiple Items","HelpMe"]
        },
        "Name": {
            "S": "Amazon DynamoDB"
        }
    }
};
 dynamodb.putItem(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

然後試試UpdateItem

 var params = {
    "TableName": "table1",
    "Key": {
        "pk_id": {
            "S": "201909270001"
        }
    },
    "UpdateExpression": "set #name = :val1, Message = :val2",
    "ExpressionAttributeValues": {
        ":val1": {"S": "Spencer"},
        ":val2": {"S": "Hello Dynamodb"}
    },
    "ExpressionAttributeNames": {
        "#name": "Name"
    },
    "ReturnValues": "ALL_NEW"
};
 dynamodb.updateItem(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

上面更新了Name的資料以及新增了Message的內容,等等...#name這什麼東西呢? 其實是因為Name是a reserved keyword,不能直接在UpdateExpression當中使用,所以要用ExpressionAttributeNames進行對應。

而ReturnValues: ALL_NEW屬性是方便我們希望指令完成時同時取得全部的最新內容。

讀取資料

接下來試試直接使用pk_id取得item

 var params = {
    "TableName": "table1",
    "Key": {
        "pk_id": {
            "S": "201909270001"
        }
    }
};
 dynamodb.getItem(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

然後會看到Name確實被更新且新增了Message訊息

{"Item":{"pk_id":{"S":"201909270001"},"Message":{"S":"Hello Dynamodb"},"Tags":{"SS":["HelpMe","Multiple Items","Update"]},"Name":{"S":"Spencer"}}}

刪除資料

因為是透過pk_id,跟讀取資料一樣很單純

 var params = {
    "TableName": "table1",
    "Key": {
        "pk_id": {
            "S": "201909270001"
        }
    }
};
 dynamodb.deleteItem(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

然後我們就抓不到資料了

{}

AWS CLI from json file

我們也可以從cli進行操作,不過因為資料描述通常都比較長,我會希望從json file描述內容。
以下試一下簡單的put-item,首先撰寫新增一個json file 如下

{
    "pk_id": {
        "S": "201909270001"
    },
    "Tags": {
        "SS": ["Update","Multiple Items","HelpMe"]
    },
    "Name": {
        "S": "Amazon DynamoDB"
    }
}

跟前面不一樣的是,我們只描述了attribute及其內容,因為put-item參數中已經指定了table name

而完整的指令如下

$ aws dynamodb put-item --table-name table1 --item file://newItem.json --endpoint-url http://localhost:8000

然後試著用get-item取得內容

$ aws dynamodb get-item --table-name table1 --key '{"pk_id":{"S":"201909270001"}}' --endpoint-url http://localhost:8000
{
    "Item": {
        "Tags": {
            "SS": [
                "HelpMe",
                "Multiple Items",
                "Update"
            ]
        },
        "pk_id": {
            "S": "201909270001"
        },
        "Name": {
            "S": "Amazon DynamoDB"
        }
    }
}

後記

因為是很簡單的item操作實驗,實際上因為DynamoDB設計特性還有很多常用或與關連資料庫很不同的參數可使用,例如attribute是否存在的條件等。希望之後有機會的時候再按照實作案例提及囉。


上一篇
Day15-環境準備(四)DynamoDB-Local
下一篇
Day17-概觀(七)NoSQL設計
系列文
從Java進入AWS部署RESTful API的心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言